#define DEBUG_TYPE "abcde"
#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/InstrTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/DominanceFrontier.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
#include "llvm/Support/raw_ostream.h"



using namespace llvm;


namespace llvm {
STATISTIC(ABCFound1, "Array Bound Check Found");


struct ABCDEPass: public FunctionPass {
	static char ID;
	ABCDEPass() :
			FunctionPass(ID) {
	}

  virtual bool doInitialization(Module &M) {
    ABCFound1 = 0;
    return false;
  }

  virtual bool doFinalization(Module &M) {
    errs() << "[ABCDE]>>>Total number of ABC checks found: "
        << ABCFound1 << '\n';
    return false;
  }

	virtual bool runOnFunction(Function &F) {
		for (Function::iterator iter = F.begin(); iter != F.end(); iter++) {
			TerminatorInst* term = iter->getTerminator();
			BranchInst* branch = dyn_cast<BranchInst>(term);
			if (0 != branch) { //Successfully casted to a branch inst
				if (branch->isConditional()) {
					BasicBlock* fb = branch->getSuccessor(1);
					if (fb->getName().startswith("ABC_Check_Fail")) {
						ABCFound1++;
						}
					}
				}
			}
		return false;
	}
};
char ABCDEPass::ID = 0;RegisterPass<ABCDEPass> Y("abcde",
		"Array Bounds Checking Detection");
}

